<template>
  <div>
    <!--     搜索条件-->
    <SearchForm @search="getDataList" @reset="resetSearch">
      <el-col :span="8" :xs="24">
        <el-form-item label="菜单名称" prop="name">
          <el-input v-model="page.name"></el-input>
        </el-form-item>
      </el-col>
      <el-col :span="8" :xs="24">
        <el-form-item label="菜单地址" prop="url">
          <el-input v-model="page.url"></el-input>
        </el-form-item>
      </el-col>
    </SearchForm>
    <el-card shadow="never" style="margin-top: 10px">

      <div style="margin-bottom: 15px;text-align: right">
        <el-button type="primary" @click="addMenu(null)" v-show="$permiss[24]">添加顶级</el-button>
      </div>
      <Table ref="table" :table-data="tableData" :table-column="tableColumn" row-key="id"
             lazy :tree-load="treeLoad"
             :page="false" border>
        <template slot="first">
          <el-table-column prop="name" label="菜单名" width="250"></el-table-column>
        </template>
        <template slot="type" slot-scope="{row}">
          {{ row.type === 0 ? '目录' : row.type === 1 ?'菜单' :'按钮' }}
        </template>
        <template slot="handle" slot-scope="{row}">
          <el-button type="text" v-show="$permiss[24]" @click="addMenu(row)">添加下级</el-button>
          <el-button type="text" v-show="$permiss[26]" @click="editMenu(row)">编辑</el-button>
          <el-button type="text" v-show="$permiss[1410]" @click="delMenu(row)">删除</el-button>
        </template>

        <el-switch slot="status" slot-scope="{row}" @change="changeStatus(row)" :value="row.status === 1"></el-switch>
      </Table>

      <Dialog @cancel="visible.isShow = false" @confirm="confirm" @close="clearForm" :visible.sync="visible.isShow"
              :title="visible.title">
        <el-form ref="form" :model="editForm" label-width="80px" :rules="rulesForm">
          <el-form-item label="菜单名称" prop='name'>
            <el-input v-model="editForm.name"></el-input>
          </el-form-item>
          <el-form-item label="国际名称" prop='languageName'>
            <el-input v-model="editForm.languageName"></el-input>
          </el-form-item>
          <el-form-item label="前端url" prop='webUrl'>
            <el-input v-model="editForm.webUrl"></el-input>
          </el-form-item>
          <el-form-item label="菜单类型" prop='type'>
            <el-radio-group v-model="editForm.type">
              <el-radio :label="1">菜单</el-radio>
              <el-radio :label="2">按钮</el-radio>
            </el-radio-group>
          </el-form-item>
          <el-form-item label="状态" prop='status'>
            <el-radio-group v-model="editForm.status">
              <el-radio :label="1">启用</el-radio>
              <el-radio :label="0">禁用</el-radio>
            </el-radio-group>
          </el-form-item>
          <el-form-item label="绑定角色" prop='rids'>
            <el-select v-model="editForm.rids" multiple style="width: 100%">
              <el-option v-for="item in roleList" :key="item.rid" :value="item.rid" :label="item.roleName"></el-option>
            </el-select>
          </el-form-item>
          <el-form-item label="接口标识">
            <el-select v-model="editForm.perms" clearable style="width: 100%">
              <el-option v-for="item in permissList" :key="item.value" :value="item.value"
                         :label="item.label"></el-option>
            </el-select>
          </el-form-item>
          <el-form-item label="菜单url" prop='url'>
            <el-input v-model="editForm.url"></el-input>
          </el-form-item>
          <el-form-item label="图标" prop='icon'>
            <el-input v-model="editForm.icon"></el-input>
          </el-form-item>
          <el-form-item label="排序" prop='orderNum'>
            <el-input-number v-model="editForm.orderNum"></el-input-number>
          </el-form-item>
        </el-form>
      </Dialog>

    </el-card>
  </div>
</template>

<script>
import {
  fetchMenuSearch,
  deleteMenu,
  permissionUpdate,
  addPermission,
  fetchPermissionRole,
  changeStatusMenu
} from '@/api/system'
import {deepClone} from "@/utils/tools";

export default {
  name: 'menuManagement',
  data() {
    return {
      page: {},
      visible: {
        isShow: false,
        title: '',
        type: 'add'
      },
      tableData: [],
      editForm: {
        rids: [],
        name: '',
        languageName: '',
        type: 1,
        icon: '',
        orderNum: null,
        url: '',
        perms: '',
        webUrl: '',
        status: 1,
      },
      dialogTitle: '',
      options: [],
      tableColumn: [
        {label: '编号', prop: 'id', align: 'center'},
        {label:'创建时间', prop: 'createTime', align: 'center', width: 150},
        {label:'url地址', prop: 'url', align: 'center', width: 200},
        {label: '菜单类型', prop: 'type', align: 'center', slot: 'type'},
        {label: '前端地址', prop: 'webUrl', align: 'center', width: 150},
        {label: '图标', prop: 'icon', align: 'center', width: 150},
        {label: '排序', prop: 'orderNum', align: 'center'},
        {label: '状态', align: 'center', slot: 'status'},
        {
          label: '操作',
          align: 'center',
          slot: 'handle',
          minWidth: '150',
          // isHide: !this.$permiss[24],
          fixed: 'right'
        },
      ],
      rulesForm: {
        name: [
          {required: true, message: '不能为空', trigger: 'blur'}
        ],
        // languageName: [
        //   {required: true, message: this.$t('不能为空'), trigger: 'blur'}
        // ],
        rids: [
          {required: true, message: '不能为空', trigger: 'change', type: 'array'}
        ]
      },
      roleList: [],
      lazyParentId: null,
      lazyId: null,
      isAddLowerLevel: false,
      lazyResolveMap: new Map(),
      tableAllData: [],
      permissList: [
        {label: '#', value: '#'},
        {label: '查询', value: 'select'},
        {label: '修改', value: 'update'},
        {label: '新增', value: 'add'},
        {label: '删除', value: 'delete'},
        {label: '导入', value: 'Import'},
        {label: '导出', value: 'export'},
      ]
    }
  },
  computed: {
    menuName() {
      return this.$i18n.locale === 'zh_CN' ? 'name' : 'languageName'
    }
  },
  mounted() {
    this.getDataList()
    this.getRoleList()
  },
  methods: {
    async getDataList() {
      const res = await fetchMenuSearch(this.page)
      if (res.code === 1) {
        const data = [...res.data].filter(i => i.parentId === 0 && i.type === 1).map(item => {
          if (item.type === 0 || item.type === 1) item.hasChildren = true
          return item
        })
        this.tableAllData = res.data
        this.tableData = data.sort((a, b) => {
          return a.orderNum - b.orderNum
        })
      }
    },

    resetSearch() {
      this.page = {}
      this.getDataList()
    },
    async getRoleList(rows = {}) {
      const res = await fetchPermissionRole({pid: rows.id})
      if (res.code === 1) {
        const keys = res.data.filter(item => item.checked).map(item => item.rid)
        this.roleList = res.data
        this.$set(this.editForm, 'rids', keys)
      }
    },
    clearForm() {
      this.editForm = {
        rids: [],
        name: '',
        languageName: '',
        type: 1,
        icon: '',
        orderNum: null,
        url: '',
        perms: '',
        webUrl: '',
        status: 1
      }
      this.isAddLowerLevel = false
      this.lazyParentId = null
      this.$refs['form'].resetFields();
    },
    async editMenu(row) {
      this.editForm = deepClone({...row})
      this.lazyParentId = row.parentId
      await this.getRoleList(row)
      this.visible = {
        isShow: true,
        title: row.name + ' - ' +  '编辑菜单',
        type: 'edit'
      }
    },
    async addMenu(rows) {
      await this.getRoleList()
      let title = '添加菜单'
      if (rows) {
        title = rows.name + ' - ' + '添加下级'
        this.editForm.type = 2
        this.editForm.id = rows.id
        this.editForm.parentId = rows.parentId
        this.lazyParentId = rows.parentId
        if (this.lazyResolveMap.size !== 0) {
          // 当前节点存在已渲染子节点，使用当前节点id做lazyParentId
          if (this.lazyResolveMap.has(rows.id)) {
            const {
              tree,
            } = this.lazyResolveMap.get(rows.id)
            this.isAddLowerLevel = true
          }
        }
      }
      this.visible = {
        isShow: true,
        title: title,
        type: 'add'
      }
    },
    async delMenu(row) {
      this.$confirm('确定删除?', '提示', {
        confirmButtonText:'确认',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(async () => {
        this.lazyParentId = row.parentId
        const res = await deleteMenu({id: row.id})
        if (res.code === 1) {
          this.$message({
            type: 'success',
            message: '删除成功'
          });
          await this.getDataList()
          await this.setUpDateTree()
        }
      });

    },
    async changeStatus(row) {
      this.editForm = {...row}
      this.lazyParentId = row.parentId
      const formData = new FormData()
      formData.append('id', row.id)
      const res = await changeStatusMenu(formData)
      if (res.code === 1) {
        this.$message.success('修改成功')
        await this.getDataList()
        await this.setUpDateTree()
      }
    },
    setUpDateTree() {
      // 懒加载数据不更新的问题
      if (this.lazyResolveMap.size !== 0) {
        const key = this.isAddLowerLevel ? this.editForm.id : this.lazyParentId
        if (key !== 0) {
          const {
            tree,
            treeNode,
            resolve
          } = this.lazyResolveMap.get(key)
          // 将数据缓存设置空
          this.$set(this.$refs.table.$children[0].store.states.lazyTreeNodeMap, key, [])
          this.treeLoad(tree, treeNode, resolve)
        }
      }
    },
    // 懒加载菜单
    treeLoad(tree, treeNode, resolve) {
      // 过滤该菜单是否有子级
      const list = this.tableAllData.filter(child => tree.id === child.parentId).map(i => {
        // 查询菜单是否有子级权限
        const childArr = this.tableAllData.filter(val => val.parentId === i.id)
        // 如果有子级添加 hasChildren
        if (childArr.length && childArr.length !== 0) {
          i.children = childArr
          i.hasChildren = true
        }
        return i
      }).sort((a, b) => {
        return a.orderNum - b.orderNum
      })
      this.lazyResolveMap.set(tree.id, {tree, treeNode, resolve})
      resolve(list)
    },
    async confirm() {
      this.$refs.form.validate(async v => {
        if (v) {
          const isAdd = this.visible.type === 'add'
          const api = (params) => isAdd ? addPermission(params) : permissionUpdate(params)
          const params = {
            ...this.editForm,
          }
          if (isAdd) {
            if (!this.editForm.id) {
              params['parentId'] = 0
            } else {
              params['parentId'] = this.editForm.id
            }
          }
          const res = await api(params)
          if (res.code === 1) {
            await this.getDataList()
            await this.setUpDateTree()
            this.$message.success(isAdd ? '添加成功' : '编辑成功')
            this.visible.isShow = false
          }
        }
      })

    }
  }
}
</script>

<style scoped>


</style>
